package unibz.thaison.iosa;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.codehaus.jettison.json.JSONObject;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.view.Viewable;

@Path("/screen")
public class ScreenService {
	private ScreenManager manager = ScreenManager.getInstance();
	static String weatherLocation = "http://api.wunderground.com/api/ae37f61e874f3512/conditions/q/IT/Bolzano.json";
	static String userLocation = "http://localhost:8080/iosa_rest/rest/user";
	
	protected Weather getWeather() throws Exception {
		Weather weather = null;
		Client client = Client.create();
		WebResource webResource = client.resource(weatherLocation);
		ClientResponse response = webResource.type(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON)
				.post(ClientResponse.class);
        if (response.getClientResponseStatus() == ClientResponse.Status.OK) {
        	String output = response.getEntity(String.class);

        	JSONObject json = new JSONObject(output);
        	if (!json.has("current_observation"))
        		throw new Exception("Invalid  format!");
        	json = json.getJSONObject("current_observation");
        	weather = new Weather();
        	JSONObject loc = json.getJSONObject("display_location");
        	weather.setPlace(loc.getString("full"));
        	weather.setLatitude(loc.getString("latitude"));
        	weather.setLongitude(loc.getString("longitude"));
        	
        	weather.setWeather(json.getString("weather"));
        	weather.setTemperature(json.getString("temperature_string"));
        	weather.setWind(json.getString("wind_string"));
        	weather.setWindDirection(json.getString("wind_dir"));
        	weather.setIconUrl(json.getString("icon_url"));
        }
        return weather;
	}
	
	protected List<User> getUsers() throws Exception {
		List<User> users = null;
		Client client = Client.create();
		WebResource webResource = client.resource(userLocation);
		ClientResponse response = webResource.type(MediaType.TEXT_PLAIN)
				.accept(MediaType.APPLICATION_JSON)
				.get(ClientResponse.class);
		if (response.getClientResponseStatus() == ClientResponse.Status.OK) {
        	String output = response.getEntity(String.class);
        	ObjectMapper mapper = new ObjectMapper();
        	users = mapper.readValue(output, new TypeReference<List<User>>(){});
        }
        return users;
	}
	
	@GET
	@Path("{screenid}")
	@Produces(MediaType.TEXT_HTML)
	public Viewable screen(@Context HttpServletRequest request,
			@PathParam("screenid") int screenId) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("E, yyyy-MM-dd 'at' h:m:s");
		Date now = new Date();
		request.setAttribute("time", formatter.format(now));
		
		Screen s = manager.get(screenId);
		
		if (s != null && s.getServiceType() == Service.WEATHER) {	
			request.setAttribute("weather", getWeather());
			return new Viewable("/WEB-INF/jsp/weather.jsp", null);
		}
		if (s != null && s.getServiceType() == Service.USERS_SUMMARY) {
			request.setAttribute("users", getUsers());
			return new Viewable("/WEB-INF/jsp/user.jsp", null);			
		}
		return new Viewable("/WEB-INF/jsp/no_service.jsp", null);
	}
	
	@Path("/manage")
	@GET
	@Produces(MediaType.TEXT_HTML)
	public Viewable manage(@Context HttpServletRequest request) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("E, yyyy-MM-dd 'at' h:m:s");
		Date now = new Date();
		request.setAttribute("time", formatter.format(now));

		request.setAttribute("screens", manager.getAll());
		request.setAttribute("services", manager.getServices());
		
		return new Viewable("/WEB-INF/jsp/manage.jsp", null);
	}
	
	@Path("/manage")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces(MediaType.TEXT_HTML)
	public Viewable change(@Context HttpServletRequest request,
			@FormParam("screen") int screenId,
			@FormParam("service") int serviceType) throws Exception {
		Screen s = manager.get(screenId);
		if (s != null)
			s.setServiceType(serviceType);
		
		return manage(request);
	}
}
